package com.qimu.saiyou.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qimu.saiyou.mapper.CompeteMapper;
import com.qimu.saiyou.model.dto.compete.CompeteQueryRequest;
import com.qimu.saiyou.model.entity.*;
import com.qimu.saiyou.model.vo.CompeteUserVo;
import com.qimu.saiyou.model.vo.CompeteVo;
import com.qimu.saiyou.service.*;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: FeiXiang
 * @description 针对表【compete(竞赛)】的数据库操作Service实现
 * @createDate 2024-02-26 19:55:51
 */
@Service
public class CompeteServiceImpl extends ServiceImpl<CompeteMapper, Compete>
        implements CompeteService {
    @Resource
    private UserService userService;
    @Resource
    private TeamService teamService;

    @Resource
    private CompeteUserService competeUserService;
    @Resource
    private UserPaperService userPaperService;

    @Override
    public Page<CompeteVo> listCompeteVoByCompetitionId(CompeteQueryRequest competeQueryRequest, HttpServletRequest request) {
        Long competitionId = competeQueryRequest.getCompetitionId();
        LambdaQueryWrapper<Compete> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Compete::getCompetitionId, competitionId);
        List<Compete> competes = this.list(lambdaQueryWrapper);
        Page<CompeteVo> competeVoPage = new Page<>();
        List<CompeteVo> competeVoList = competes.stream().map(this::getCompeteVo).collect(Collectors.toList());
        competeVoPage.setRecords(competeVoList);
        return competeVoPage;
    }

    @Override
    public CompeteVo getCompeteVo(Compete compete) {
        CompeteVo competeVo = CompeteVo.objToVo(compete);
        Long blueTeamId = compete.getBlueTeamId();
        Long redTeamId = compete.getRedTeamId();
        List<Long> blueTeamIds = new ArrayList<>();
        List<Long> redTeamIds = new ArrayList<>();
        if (blueTeamId != null && blueTeamId > 0) {
            Team blueTeam = teamService.getById(blueTeamId);
            competeVo.setBlueTeam(teamService.getTeamVO(blueTeam));
            if (blueTeam != null) {
                blueTeamIds = JSONUtil.toList(blueTeam.getUsersId(), Long.class);
                long blueSum = userPaperService.lambdaQuery().in(UserPaper::getUserId, blueTeamIds).list().stream().mapToLong(UserPaper::getTotalScore).sum();
                competeVo.setBlueScore(blueSum);
            }
            if (redTeamId != null && redTeamId > 0) {
                Team redTeam = teamService.getById(redTeamId);
                competeVo.setRedTeam(teamService.getTeamVO(redTeam));
                if (redTeam != null) {
                    redTeamIds = JSONUtil.toList(redTeam.getUsersId(), Long.class);
                    long redSum = userPaperService.lambdaQuery().in(UserPaper::getUserId, redTeamIds).list().stream().mapToLong(UserPaper::getTotalScore).sum();
                    competeVo.setRedScore(redSum);
                }
            }
        }
        if (ObjectUtils.allNull(competeVo.getRedTeam(), competeVo.getBlueTeam())) {
            return null;
        }
        List<Long> allTeamList = Stream.of(blueTeamIds, redTeamIds)
                .flatMap(List::stream)
                .collect(Collectors.toList());
        List<CompeteUserVo> competeUserVoList = allTeamList.stream().map(userId -> getCompeteUserVo(userId, compete.getId())).collect(Collectors.toList());
        competeVo.setCompeteUserList(competeUserVoList);
        return competeVo;

    }

    @Override
    public CompeteUserVo getCompeteUserVo(Long userId, Long competeId) {
        LambdaQueryWrapper<CompeteUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompeteUser::getUserId, userId);
        queryWrapper.eq(CompeteUser::getCompeteId, competeId);
        CompeteUser competeUser = competeUserService.getOne(queryWrapper);
        CompeteUserVo competeUserVo = new CompeteUserVo();
        BeanUtils.copyProperties(competeUser, competeUserVo);
        return competeUserVo;
    }

    @Override
    public Page<CompeteVo> listCompeteVoByTeamId(CompeteQueryRequest competeQueryRequest, HttpServletRequest request) {
        Long teamId = competeQueryRequest.getTeamId();
        LambdaQueryWrapper<Compete> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Compete::getBlueTeamId, teamId).or()
                .eq(Compete::getRedTeamId, teamId);
        List<Compete> competes = this.list(lambdaQueryWrapper);
        Page<CompeteVo> competeVoPage = new Page<>();
        List<CompeteVo> competeVoList = competes.stream().map(this::getCompeteVo).collect(Collectors.toList());
        competeVoPage.setRecords(competeVoList);
        return competeVoPage;
    }

    @Override
    public Page<CompeteVo> listMyCompeteVoPage(User loginUser) {
        LambdaQueryWrapper<CompeteUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompeteUser::getUserId, loginUser.getId());
        Page<CompeteVo> competeVoPage = new Page<>();
        List<CompeteUser> competeUserList = competeUserService.list(queryWrapper);
        if (CollUtil.isEmpty(competeUserList)) {
            return competeVoPage;
        }
        List<Long> competeIdList = competeUserList.stream().map(CompeteUser::getCompeteId).collect(Collectors.toList());
        List<Compete> competes = this.listByIds(competeIdList);
        List<CompeteVo> competeVoList = competes.stream().map(this::getCompeteVo).collect(Collectors.toList());
        competeVoPage.setRecords(competeVoList);
        return competeVoPage;
    }

    @Override
    public CompeteVo listCompeteVoById(CompeteQueryRequest competeQueryRequest, HttpServletRequest request) {
        Long teamId = competeQueryRequest.getId();
        Compete compete = this.getById(teamId);
        return getCompeteVo(compete);
    }
}




